﻿#include "machine.h"
#include <QTime>
#include <QApplication>

/*
Machine的dll如果是Release版本的在应用程序中只能在Release下调用，
否则调用不成功（连接不上）,Machine的dll如果是Debug版本,
应用程序中在Debug下调用成功；
*/

//------------------------------------------

QByteArray g_receiveBuff;
DataExFuns g_exfuns = {NULL,NULL,NULL,NULL,NULL};

// 发送数据
int operatorSendData(u8 * pDatBuf, int len)
{
    if (pDatBuf != NULL && len != 0)
    {
        // 不准备通过该函数发送数据
    }
    return 0;
}

// 得到发送缓冲区空闲长度
int operatorGetSdFreeLen(void)
{
    return 0;  // 认没有空间
}

// 接收数据
int operatorGetData(u8 * pDat, int expectLen)
{
    int len = g_receiveBuff.size();
    if (len > expectLen)
    {
        len = expectLen;
    }

    //if (len != 0 && pDat != NULL)
    if (len == expectLen && pDat != NULL)  //使len等于expectLen(串口下接收数据暴露的问题)
    {
        memcpy(pDat, g_receiveBuff.data(), len);
        g_receiveBuff.remove(0, len);
    }
    else
    {
        len = 0;
    }

    return len;
}

// 已接收数据长度
int operatorGetRsLen(void)
{
    return g_receiveBuff.size();
}

void delayMs(u32 ms)
{
    QDateTime oldTime, curTime;
    oldTime = QDateTime::currentDateTime();
    while(1)
    {
        curTime = QDateTime::currentDateTime();
        if(oldTime.msecsTo(curTime) > ms)
        {
            break;
        }
    }
}

void initDataExFuns(void)
{
    g_exfuns.sendCommData = operatorSendData;
    g_exfuns.getCommData = operatorGetData;
    g_exfuns.getRsvLen = operatorGetRsLen;
    g_exfuns.getTrsFreeLen = operatorGetSdFreeLen;

    g_exfuns.delay = delayMs;
}

//------------------------------------------


Machine::Machine(QObject *parent) :
    QObject(parent),
    m_pTcpThread(NULL),
    m_pTcpClient(NULL),
    m_pComThread(NULL),
    m_pComPort(NULL),
    m_startComm(0)
{
    memset(&m_mcStatus, 0, sizeof(MCStatus));           // 机器状态
    memset(&m_mcPara, 0, sizeof(ParaStruct));           // 机器参数信息
    memset(&m_wkPara, 0, sizeof(ParaStruct));           // 工作参数信息
    memset(&m_mcPrePara, 0, sizeof(ParaStruct));           // 机器预留参数信息
    memset(&m_wkPrePara, 0, sizeof(ParaStruct));           // 工作预留参数信息
    memset(&m_mcInfo,0,sizeof(MCInfo));                 // 机器信息
    memset(&m_lotData,0,sizeof(McLotData));                // 物联数据

    memset(&m_sensorsStaDat, 0, sizeof(SensorsBitmap));        // 传感器信号状态位图
    memset(&m_sensorEnBmp, 0, sizeof(SensorsBitmap));        // 传感器信号有效位图

    memset(&m_transCtrl, 0, sizeof(FileTransCtrl));     // 文件传输信息

    m_pSendTimer = new QTimer(this);
    m_pSendTimer->setInterval(100);    // 设置定时间隔100毫秒
    connect(m_pSendTimer, SIGNAL(timeout()), this, SLOT(onSendTimer()));
    m_transCtrl.pFileHead = new DataDs16FileHead;
    m_transCtrl.pAppHead  = new AppFileHead;
    m_transCtrl.pDatBuff  = new u8[MAX_FILE_SIZE];
    m_startComm = 0;
    m_connected = 0;
    m_statusEn = 0;
    m_mcParaEn = 0;
    m_wkParaEn = 0;
    m_gainParaEn = 0;
    m_mcPreParaEn = 0;
    m_wkPreParaEn = 0;
    m_sensorStaEn = 0;
    m_sensorBmpEn = 0;

    m_statusToggle = 0;
    m_fileTransEn = 0;
    m_transBreak = 0;
    m_totalSendNum = 0;
    m_totalPacketNum = 0;
    m_connectMode = 0;

    initDataExFuns();
}

Machine::~Machine()
{
    if (m_startComm != 0)
    {
        if(m_connectMode == USE_TCP_COMM)
        {
            m_pTcpThread->quit();
            m_pTcpThread->wait();
        }
        else if(m_connectMode == USE_SERIAL_COMM)
        {
            m_pComThread->quit();
            m_pComThread->wait();
        }
    }
    if (m_transCtrl.pFileHead != NULL)
    {
        delete []m_transCtrl.pFileHead;
        m_transCtrl.pFileHead = NULL;
    }
    if (m_transCtrl.pDatBuff != NULL)
    {
        delete []m_transCtrl.pDatBuff;
        m_transCtrl.pDatBuff = NULL;
    }

    if(m_connectMode == USE_TCP_COMM)
    {
        if(m_pTcpThread != NULL)
        {
            delete m_pTcpThread;
        }
    }
    else if(m_connectMode == USE_SERIAL_COMM)
    {
        if(m_pComThread != NULL)
        {
            delete m_pComThread;
        }
    }
}

//初始化通讯连接方式
void Machine::initConnectMode(s16 val)
{
    m_connectMode = val;
    if(m_connectMode == USE_TCP_COMM)//网口
    {
        m_pTcpThread = new QThread();
        m_pTcpClient = new TcpClient();
    }
    else if(m_connectMode == USE_SERIAL_COMM)//串口
    {
        m_pComThread = new QThread();
        m_pComPort = new ComPort();
        connect(m_pComPort, SIGNAL(siSerialPortOpenState(int)), this, SLOT(slIfOpenSerialPort(int)) );
    }
}

void Machine::setConfigFileName(QString configfilename)
{
    m_configFileName = configfilename;
    if(m_connectMode == USE_TCP_COMM)//网口
    {
        m_pTcpClient->setConfigFileName(m_configFileName);
    }
}

//设置串口名称
void Machine::setComportName(QString portName)
{
    if(m_pComPort == NULL)
    {
        return;
    }

    if(m_connectMode == USE_SERIAL_COMM)//串口
    {
        m_pComPort->setComPortName(portName);
    }
}

QString Machine::getConfigFileName()
{
    return m_configFileName;
}

int Machine::startCommunication()
{
    if (m_startComm == 0)
    {
        //   qDebug() << "Machine " << QThread::currentThread();

        if(m_connectMode == USE_TCP_COMM)//网口
        {
            if (m_configFileName.isEmpty())
            {
                qDebug() << "mast call SetConfigFileName first ";
            }

            m_pTcpClient->moveToThread(m_pTcpThread);     // 移动对象到线程中

            //    connect(qApp, SIGNAL(finished()), m_pTcpThread, SLOT(finished()));

            connect(m_pTcpThread, SIGNAL(started()), m_pTcpClient, SLOT(connectToServer()) );
            connect(m_pTcpThread, SIGNAL(finished()), m_pTcpClient, SLOT(deleteLater()) );  // 退出删除对象

            connect(m_pTcpClient, SIGNAL(siConnectSta(int)),
                    this, SLOT(slotConnectSta(int)), Qt::AutoConnection);             // 连接状态改变
            connect(m_pTcpClient, SIGNAL(siConnectErr(QString)),
                    this, SLOT(slotConnectErr(QString)), Qt::AutoConnection);         // 接收到通讯错误
            connect(m_pTcpClient, SIGNAL(siReceiveData(QByteArray)),
                    this, SLOT(slotReceiveData(QByteArray)), Qt::AutoConnection);     // 接收到数据
            connect(this, SIGNAL(siSendData(QByteArray)),
                    m_pTcpClient, SLOT(slotSendData(QByteArray)), Qt::AutoConnection); // 发送数据的槽

            m_pTcpThread->start();    // 启动线程
        }

        if(m_connectMode == USE_SERIAL_COMM)//串口
        {
            m_pComPort->moveToThread(m_pComThread);

            connect(m_pComThread, SIGNAL(started()), m_pComPort, SLOT(initComm()) );
            connect(m_pComThread, SIGNAL(finished()), m_pComPort, SLOT(deleteLater()) );  // 退出删除对象

            connect(m_pComPort, SIGNAL(siReceiveData(QByteArray)),
                    this, SLOT(slotReceiveData(QByteArray)), Qt::QueuedConnection);       // 接收到数据
            connect(this, SIGNAL(siSendData(QByteArray)),
                    m_pComPort, SLOT(slotSendData(QByteArray)), Qt::QueuedConnection); // 发送数据的槽

            m_pComThread->start();  // 启动线程
        }
        m_startComm = 1;
    }
    return m_startComm;
}

// 连接状态改变的槽函数
void Machine::slotConnectSta(int sta)
{
    //    qDebug() << "SlotConnectSta" << sta;
    m_connected = sta;
}

// 接收到通讯错误槽函数
void Machine::slotConnectErr(QString errinfo)
{
    if(errinfo.length() <= 0){}
    //qDebug() << "SlotConnectErr" << errinfo;
}

void Machine::setMcStatusAsMc(u8* buff, int toggle)
{
    memcpy(&m_mcStatus, buff, sizeof(MCStatus));
    m_statusEn = 1;
    emit(siStatusChange(toggle));
}

// 接收到数据的槽函数
void Machine::slotReceiveData(QByteArray dat)
{
    int rslt;
    DataPacket packet;
    OperPacket * operpkt = (OperPacket *)(&packet);

    //    qDebug() << "SlotReceiveData size=" << dat.size();

    g_receiveBuff.append(dat);
    //qDebug()<<"append dat size"<<dat.size();
    do
    {
        rslt = getANormalPacket(&g_exfuns, &packet);
        // 分析数据包，并执行
        if (rslt > 0)	// 收到数据包
        {
            //qDebug()<<"getANormalPacket rslt="<<rslt<<operpkt->packet.fldp.cmd;
            switch(operpkt->packet.fldp.cmd)	// 先按固定长度解析
            {
            case DCMD_REQUEST_DAT:          	// 请求文件数据
            {
                if (m_transCtrl.transActive == TRANS_ACTIVE)
                {
                    if (1   &&
                            m_transCtrl.transflag == TRANS_REQUEST &&       // 请求传输数据模式
                            m_transCtrl.fileType    == operpkt->dRequestDatBlock.fileType &&
                            m_transCtrl.fileIdx     == operpkt->dRequestDatBlock.fileIdx &&
                            m_transCtrl.fileId      == operpkt->dRequestDatBlock.fileId &&
                            1   )
                    {
                        qDebug("in request mode, send block idx=%d", operpkt->dRequestDatBlock.datBlockIdx);
                        transFileData(m_transCtrl, operpkt->dRequestDatBlock.datBlockIdx);
                    }
                }
                break;
            }
            case DCMD_SEND_MC_INFO:         	// 发送机器信息
            {
                memcpy(&m_mcInfo, operpkt->dSendMcInfo.exData, sizeof(MCInfo));
                emit(siMcInfoChange( ));

                break;
            }

            case DCMD_SEND_MC_STATUS:			// 发送机器状态
            {
                setMcStatusAsMc(operpkt->dSendMcStatus.exData, operpkt->dSendMcStatus.toggle);
                break;
            }

            case DCMD_SEND_MC_PARAS:			// 发送机器参数
            {
                int type;

                type = operpkt->dSendMcParas.paraType;
                if (operpkt->dSendMcParas.exLen == sizeof(ParaStruct))
                {
                    if (type == SEW_MCPARA_MACH || type == SEW_MCPARA_DEF_MC)
                    {
                        memcpy(&m_mcPara, operpkt->dSendMcParas.exData, sizeof(ParaStruct));
                        m_mcParaEn = 1;
                    }
                    else if (type == SEW_MCPARA_WORK || type == SEW_MCPARA_DEF_WK)
                    {
                        memcpy(&m_wkPara, operpkt->dSendMcParas.exData, sizeof(ParaStruct));
                        m_wkParaEn = 1;
                    }
                    //平板切割机(增益)
                    else if (type == DCMD_SEND_MOTO_GAINPARA)
                    {
                        memcpy(&m_gainPara, operpkt->dSendMcParas.exData, sizeof(KnifeGapPara));
                        m_gainParaEn = 1;
                    }
                    else if (type == SEW_REVMCPARA_MACH || type == SEW_MCPARA_DEF_MC)
                    {
                        memcpy(&m_mcPrePara, operpkt->dSendMcParas.exData, sizeof(ParaStruct));
                        m_mcPreParaEn = 1;
                    }
                    else if (type == SEW_REVMCPARA_WORK || type == SEW_MCPARA_DEF_WK)
                    {
                        memcpy(&m_wkPrePara, operpkt->dSendMcParas.exData, sizeof(ParaStruct));
                        m_wkPreParaEn = 1;
                    }
                    else
                    {
                        break;
                    }

                    //因为之前请求了机器参数和工作参数，所以当两个参数都返回时，再触发信号和槽
                    //  if( m_mcParaEn==1 && m_wkParaEn==1)
                    {
                        printf("emit SiParaChange\r\n");
                        emit(siParaChange(type, 0));
                    }
                }
                else if (operpkt->dSendMcParas.exLen == sizeof(u32))
                {
                    int id, idx;
                    id = operpkt->dSendMcParas.paraId;
                    idx = id - 1;
                    if (idx > 0 && idx < PARA_NUM)
                    {
                        idx *= sizeof(u32);
                        if (type == SEW_MCPARA_MACH)
                        {
                            memcpy((u8*)(&m_mcPara)+idx, operpkt->dSendMcParas.exData, sizeof(u32));
                            m_mcParaEn = 1;
                        }
                        else if (type == SEW_MCPARA_WORK)
                        {
                            memcpy((u8*)(&m_wkPara)+idx, operpkt->dSendMcParas.exData, sizeof(u32));
                            m_wkParaEn = 1;
                        }
                        else if (type == DCMD_SEND_MOTO_GAINPARA)
                        {
                            memcpy((u8*)(&m_gainPara)+idx, operpkt->dSendMcParas.exData, sizeof(u32));
                            m_gainParaEn = 1;
                        }
                        else if (type == SEW_REVMCPARA_MACH)
                        {
                            memcpy((u8*)(&m_mcPrePara)+idx, operpkt->dSendMcParas.exData, sizeof(u32));
                            m_mcPreParaEn = 1;
                        }
                        else if (type == SEW_REVMCPARA_WORK)
                        {
                            memcpy((u8*)(&m_wkPrePara)+idx, operpkt->dSendMcParas.exData, sizeof(u32));
                            m_wkPreParaEn = 1;
                        }
                        else
                        {
                            break;
                        }
                        emit(siParaChange(type, id));
                    }
                }

                break;
            }
            case DCMD_SEND_SENSORS:         	// 发送传感信号
            {
                int len;
                len = sizeof(SensorsBitmap);
                if (len > operpkt->dSendSensors.exLen)
                {
                    len = operpkt->dSendSensors.exLen;
                }
                memset(m_sensorsStaDat.bitmap, 0, sizeof(SensorsBitmap));
                memcpy(m_sensorsStaDat.bitmap, operpkt->dSendSensors.exData, len);
                m_sensorStaEn = 1;
                //qDebug("get DCMD_SEND_SENSORS");
                emit(siSensorChange(m_sensorsStaDat));
                break;
            }
            case DCMD_SEND_FILE_INFO:			// 发送文件信息
            {

                break;
            }
            case DCMD_SEND_TRANS_RESULT:		// 发送传输结果
            {
                printf("get DCMD_SEND_TRANS_RESULT\r\n");
                m_transCtrl.lenBmp = operpkt->dSendTransResult.exLen;
                m_transCtrl.transActive = operpkt->dSendTransResult.active;
                m_transCtrl.transflag = operpkt->dSendTransResult.result;
                if (m_transCtrl.lenBmp != 0)
                {
                    memcpy(m_transCtrl.rsvBitmap, operpkt->dSendTransResult.exData, m_transCtrl.lenBmp);
                }
                m_fileTransEn = 1;

                emit (siTransResultChange());

                break;
            }
            case DCMD_SEND_SENSOR_BMP:		// 传感器信号有效位图
            {
                int len;
                len = sizeof(SensorsBitmap);
                if (len > operpkt->dSendSensorBmp.exLen)
                {
                    len = operpkt->dSendSensorBmp.exLen;
                }
                memset(m_sensorEnBmp.bitmap, 0, sizeof(SensorsBitmap));
                memcpy(m_sensorEnBmp.bitmap, operpkt->dSendSensorBmp.exData, len);
                m_sensorBmpEn = 1;
                qDebug("get DCMD_SEND_SENSOR_BMP");

                emit (siSensorEnBitmap(m_sensorEnBmp));
                break;
            }

            case  DCMD_SEND_LOTDATA:// 发送物联网数据
            {
                memcpy(&m_lotData, operpkt->dSendMcInfo.exData, sizeof(McLotData));
                //再定义一个结构体
                emit(siReceiveLotData());

                break;
            }

            case UCMD_SET_FILE_PARAS://边框检查超限后重新设置起始点
            {
                DataFilePos newPos;
                memset(&newPos, 0, sizeof(DataFilePos));
                memcpy((u8*)&newPos, operpkt->setFileParas.exData, sizeof(DataFilePos));
                //qDebug()<<"siDataFilePos";
                emit(siDataFilePos(newPos));
                break;
            }

            default:
                break;
            }
        }
        else
        {
            break;
        }
    }while(1);
}

//-------------------------------------------------------------------
// 读取机器信息
void Machine::getInfoFromMachine()
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.getMcInfo.cmdCode = UCMD_GET_MC_INFO;

    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

// 读取机器状态
int Machine::getStatusFromMachine()
{
    int rslt;
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.getMcStatus.cmdCode = UCMD_GET_MC_STATUS;
    sendPacket.getMcStatus.toggle = m_statusToggle;
    rslt = m_statusToggle;
    m_statusToggle++;
    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
    return rslt;
}

// 读取机器物联数据
void Machine::getNetDataFromMachine()
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.boardPara.cmdCode = UCMD_GET_LOT_DATA;
    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

// 读取机器参数
void Machine::getParasFromMachine(int type, int id)
{
    int mctype = -1;
    int wktype = -1;
    int gainType = -1;
    if (type == -1)
    {
        mctype = SEW_MCPARA_MACH;
        wktype = SEW_MCPARA_WORK;
        gainType = DCMD_SEND_MOTO_GAINPARA;
        m_mcParaEn = 0;
        m_wkParaEn = 0;
        m_gainParaEn = 0;
    }
    else
    {
        if(type == SEW_MCPARA_MACH )
        {
            mctype = SEW_MCPARA_MACH;
            m_mcParaEn = 0;
        }
        if(type == SEW_MCPARA_WORK )
        {
            wktype = SEW_MCPARA_WORK;
            m_wkParaEn = 0;
        }
        if(type == DCMD_SEND_MOTO_GAINPARA )
        {
            gainType = DCMD_SEND_MOTO_GAINPARA;
            m_gainParaEn = 0;
        }
    }

    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.getMcParas.cmdCode = UCMD_GET_MC_PARAS;

    if (mctype == SEW_MCPARA_MACH)
    {
        sendPacket.getMcParas.paraType = (u16)mctype;
        sendPacket.getMcParas.paraId = (u16)id;
        packetAFLDP(&sendPacket.packet);

        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
        emit(siSendData(dat));
    }

    if (wktype == SEW_MCPARA_WORK)
    {
        sendPacket.getMcParas.paraType = (u16)wktype;
        sendPacket.getMcParas.paraId = id;
        packetAFLDP(&sendPacket.packet);

        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
        emit(siSendData(dat));
    }

    if (gainType == DCMD_SEND_MOTO_GAINPARA)
    {
        sendPacket.getMcParas.paraType = (u16)gainType;
        sendPacket.getMcParas.paraId = id;
        packetAFLDP(&sendPacket.packet);
        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
        emit(siSendData(dat));
    }
}

// 读取传感信号
void Machine::getSensorsFromMachine(int backtype)
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.getSensors.cmdCode = UCMD_GET_SENSORS;
    sendPacket.getSensors.backType = (u16)backtype;

    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

// 读取传输结果
void Machine::getTransResultFromMachine(int fileid)
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.getTransResult.cmdCode = UCMD_GET_TRANS_RESULT;
    sendPacket.getTransResult.fileId = (u16)fileid;
    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

// 获取传感器有效标志位图
void Machine::getSensorEnBmpFromMachine()
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.getSensorBmp.cmdCode = UCMD_GET_SENSOR_BMP;
    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

//-------------------------------------------------------------------
//----------------------------设置状态命令
#ifdef UCMD_SET_MC_STATUS
// 清除错误

void Machine::setMcStatus(int stacode, int para)
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.setMcStatus.cmdCode = UCMD_SET_MC_STATUS;
    sendPacket.setMcStatus.staCode = (u16)stacode;
    sendPacket.setMcStatus.para = (u16)para;
    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

void Machine::cleanError()
{
    setMcStatus(MC_STA_CLENA_ERR);
}

// 设置允许工作状态
void Machine::setEnableWorkSta()
{
    setMcStatus(MC_STA_EN_WORK);
}

// 设置禁止工作状态
void Machine::setDisableWorkSta()
{
    setMcStatus(MC_STA_DIS_WORK);
}

// 设置允许工作时间状态
void Machine::setEnableWorkTime()
{
    setMcStatus(MC_STA_EN_TIME);
}

// 设置禁止工作时间状态
void Machine::setDisableWorkTime()
{
    setMcStatus(MC_STA_DIS_TIME);
}

// 重置产量
void Machine::resetOutput()
{
    setMcStatus(MC_CLEAN_COUNT);
}

// 手动工作状态
void Machine::setToManualWork()
{
    setMcStatus(MC_STA_MANUAL);
}

// 自动工作状态
void Machine::setToAutoWork()
{
    setMcStatus(MC_STA_AUTO);
}

// 文件切换
void Machine::switchWorkFile(int idx)
{
    setMcStatus(MC_FILE_SWITCH, idx);
}

// 设置经过的时间(即关机时间)
void Machine::setShutDownTime(u8 type, u32 time)
{
    int rslt;
    OperPacket sendPacket;
    //int size = sizeof(ParaStruct);
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.setElapsedTime.cmdCode = UCMD_SET_ELAPSED_TIME;
    sendPacket.setElapsedTime.type = type;
    sendPacket.setElapsedTime.time = time;

    rslt = packetAFLDP(&sendPacket.packet);

    if (rslt == 0)
    {
        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
        emit(siSendData(dat));
    }
}

void Machine::setHeadSpacingToMachine(int type, QByteArray data, u16 paraId)
{
    int rslt;
    OperPacket sendPacket;
    int size = data.size();
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.setParas.cmdCode = UCMD_SET_MC_PARAS;
    sendPacket.setParas.paraType = (u16)type;
    sendPacket.setParas.paraId = paraId;

    rslt = packetAVLDP(&sendPacket.packet, (u8*)data.data(), size);

    if(rslt == 0)
    {
        QByteArray dat((char*)(&sendPacket.packet),  LEN_NORMAL_PACKET + size);
        emit siSendData(dat);
    }
}

// 文件失效
void Machine::invalidateWorkFile(int idx)
{
    setMcStatus(MC_INVALID_FILE, idx);
}

// 清除刷新参数标志
void Machine::cleanNewParaFlag()
{
    setMcStatus(MC_CLEAN_PARA_REF);
}

// 模拟工作状态
void Machine::setSimulateWork()
{
    setMcStatus(MC_SET_TO_SIMULATE);
}

// 正常工作状态
void Machine::setNormalWork()
{
    setMcStatus(MC_SET_TO_NORMAL);
}

//退出断线测试
void Machine::exitDetectTest()
{
    setMcStatus(MC_STA_EXIT_THREADBK);
}

// 底线计数复位
void Machine::resetBobbinCounter()
{
    setMcStatus(MC_CLEAN_BOBBIN);
}
// 产量清零
void Machine::outputReset()
{
    setMcStatus(MC_CLEAN_COUNT);
}

//  设置为 进入 扫描传感器状态
void Machine::entrySensorScan()
{
    //
    setMcStatus(MC_SET_ENTRY_SCAN_SENSOR);
}

//  设置为 退出 扫描传感器状态
void Machine::exitSensorScan()
{
    //
    setMcStatus(MC_SET_EXIT_SCAN_SENSOR);
}


#endif

//----------------------------

void Machine::setParasToMachine(int type, ParaStruct & para)
{
    int rslt;
    OperPacket sendPacket;
    int size = sizeof(ParaStruct);
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.setParas.cmdCode = UCMD_SET_MC_PARAS;
    sendPacket.setParas.paraType = (u16)type;

    rslt = packetAVLDP(&sendPacket.packet, (u8*)&para, size);

    if (rslt == 0)
    {
        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET + size);
        emit(siSendData(dat));
    }
}

void Machine::setAParasToMachine(int type, int idx, u32 value)
{
    int rslt;
    OperPacket sendPacket;
    int size = sizeof(value);
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.setParas.cmdCode = UCMD_SET_MC_PARAS;
    sendPacket.setParas.paraType = (u16)type;
    sendPacket.setParas.paraId = idx;

    rslt = packetAVLDP(&sendPacket.packet, (u8*)&value, size);

    if (rslt == 0)
    {
        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET + size);
        emit(siSendData(dat));
    }
}

void Machine::setMcPara(ParaStruct * pPara)
{
    if (pPara == NULL)
    {
        return;
    }
    int size = sizeof(ParaStruct);
    memcpy(&m_mcPara, pPara, size);
    setParasToMachine(SEW_MCPARA_MACH, m_mcPara);
}

void Machine::setWkPara(ParaStruct * pPara)
{
    if (pPara == NULL)
    {
        return;
    }
    int size = sizeof(ParaStruct);
    memcpy(&m_wkPara, pPara, size);
    setParasToMachine(SEW_MCPARA_WORK, m_wkPara);
}

void Machine::setMcPrePara(ParaStruct *pPara)
{
    if (pPara == NULL)
    {
        return;
    }
    int size = sizeof(ParaStruct);
    memcpy(&m_mcPrePara, pPara, size);
    setParasToMachine(SEW_REVMCPARA_MACH, m_mcPrePara);
}

void Machine::setWkPrePara(ParaStruct *pPara)
{
    if (pPara == NULL)
    {
        return;
    }
    int size = sizeof(ParaStruct);
    memcpy(&m_wkPrePara, pPara, size);
    setParasToMachine(SEW_REVMCPARA_WORK, m_wkPrePara);
}

void Machine::setAMcPara(int id, u32 value)
{
    setAParasToMachine(SEW_MCPARA_MACH, id, value);
}

void Machine::setAWkPara(int id, u32 value)
{
    setAParasToMachine(SEW_MCPARA_WORK, id, value);
}

void Machine::setAMcPrePara(int id, u32 value)
{
    setAParasToMachine(SEW_REVMCPARA_MACH, id, value);
}

void Machine::setAWkPrePara(int id, u32 value)
{
    setAParasToMachine(SEW_REVMCPARA_WORK, id, value);
}

void Machine::setHeadSpacing(DsrHeadEx62 para)
{
    //分两个包发送
    QByteArray pkg1((char *)(&para), sizeof(DsrHeadEx62)/2);
    QByteArray pkg2((char *)(&para) + sizeof(DsrHeadEx62)/2, sizeof(DsrHeadEx62)/2);
    setHeadSpacingToMachine(SEW_MCPARA_EX1, pkg1, 0);
    setHeadSpacingToMachine(SEW_MCPARA_EX2, pkg2, 1);
}

// 设置文件参数
void Machine::setFilePara(int fileidx, int fileid, DataFilePara & filePara)
{
    int rslt;
    OperPacket sendPacket;
    int size = sizeof(DataFilePara);

    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.setFileParas.cmdCode = UCMD_SET_FILE_PARAS;
    sendPacket.setFileParas.fileType = FILE_TYPE_DAT;
    sendPacket.setFileParas.fileIdx = (u8)fileidx;
    sendPacket.setFileParas.fileId = (u16)fileid;

    rslt = packetAVLDP(&sendPacket.packet, (u8*)&filePara, size);

    if (rslt == 0)
    {
        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET + size);
        emit(siSendData(dat));
    }
}

// 设置执行进度
void Machine::setFileExecProgress(int fileidx, int fileid, FileExecPara & fileExecPara)
{
    int rslt;
    OperPacket sendPacket;
    int size = sizeof(FileExecPara);

    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.setFileParas.cmdCode = UCMD_SET_EXEC_PROGRESS;
    sendPacket.setFileParas.fileType = FILE_TYPE_DAT;
    sendPacket.setFileParas.fileIdx = (u8)fileidx;
    sendPacket.setFileParas.fileId = (u16)fileid;

    rslt = packetAVLDP(&sendPacket.packet, (u8*)&fileExecPara, size);
    if (rslt == 0)
    {
        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET + size);
        emit(siSendData(dat));
    }
}

// 设置默认参数
void Machine::setToDefaultParas(int type, u8 id, u8 nodeType)
{
    int rslt;
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.setDefParas.cmdCode = (u16)type;
    sendPacket.setDefParas.id = id;
    sendPacket.setDefParas.nodeType = nodeType;
    rslt = packetAFLDP(&sendPacket.packet);

    if(rslt != 0)
    {
        //为了去掉构建警告
    }

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

//-------------------------------------------------------------------
// 手动动作
void Machine::actionByhand(int actcode, int para1, int para2, int para3)
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.actByhand.cmdCode = UCMD_ACT_BYHAND;
    sendPacket.actByhand.actCode = (u16)actcode;
    sendPacket.actByhand.para1 = (u16)para1;
    sendPacket.actByhand.para2 = (u16)para2;
    sendPacket.actByhand.para3 = (u16)para3;

    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}
//-------------------------------------------------------------------

// 电机归零（辅助调试的功能，无安全保护和逻辑关系）
void Machine::motoToZero(int obj)
{
    actionByhand(MOTO_TO_ZERO, obj);
}

// 电机移动（辅助调试的功能，无安全保护和逻辑关系）
void Machine::motoMove(int obj, int dir, int spd)
{
    actionByhand(MOVE_BY_HAND, obj, dir, spd);
}

// 拉料移动（辅助调试的功能，无安全保护和逻辑关系）   coco
void Machine::pullMove(int obj, int dir, int spd)
{
    actionByhand(MANUAL_ACTION, obj, dir, spd);
}

// 输出控制（辅助调试的功能，无安全保护和逻辑关系）
void Machine::outputCtrl(int obj, int act, int para)
{
    actionByhand(OUTPUT_CTRL, obj, act, para);
}

// 电机使能控制（辅助调试的功能，无安全保护和逻辑关系）
void Machine::motoServoCtrl(int obj, int onoff)
{
    actionByhand(MOTO_EN_CTRL, obj, onoff);
}

// 缝纫主轴使能控制
void Machine::sewingMsServoOn()
{
    motoServoCtrl(MT_LM, MT_SERVO_ON);
}
void Machine::sewingMsServoOff()
{
    motoServoCtrl(MT_LM, MT_SERVO_OFF);
}

// 手动动作功能（日常使用功能，有安全保护和逻辑时序关系）
void Machine::manualAction(int obj, int para2, int para3)
{
    actionByhand(MANUAL_ACTION, obj, para2, para3);
}

// 手动剪线
void Machine::cutThreadByhand()
{
    manualAction(CUT_THREAD);
}

void Machine::makeup(int mode)
{
        manualAction(mode);
}

// 针梭校对
// step是指执行针梭校对的第几步
// 1表示高位提升 2表示梭归零，  3表示针归零    4表示针梭复位     0表示自动执行步骤1234
void Machine::msAdjust(int step)
{
    manualAction(MAINSHAFT_ADJUST, step);
}

// 旋转校对
void Machine::rotaAdjust(int step)
{
    manualAction(ROTATE_ADJUST, step);
}

// 机头升降
void Machine::sewHeadLiftUpDown()
{
    manualAction(HEAD_LIFT_UPDW);
}

// 粗线布线机机头升降     coco
void Machine::ThicklineSewHeadLiftUpDown()
{
//    if(headup == 0)
//    {
//        outputCtrl(HEAD_LIFT_UPDW,DOWN_CLOSE_OFF,0);
//        headup = 1;
//        return headup;
//    }
//    else
//    {
//        outputCtrl(HEAD_LIFT_UPDW,UP_OPEN_ON,0);
//        headup = 0;
//        return headup;
//    }

    manualAction(HEAD_LIFT);
//      outputCtrl(HEAD_LIFT_UPDW);

}

// 机头上升
void Machine::sewHeadLiftUp()
{
    manualAction(HEAD_LIFT_UP);
}
// 机头下降
void Machine::sewHeadLiftDown()
{
    manualAction(HEAD_LIFT_DOWN);
}

// 缝纫主轴研车
void Machine::sewingMsRun()
{
    manualAction(SEWING_MS_RUN);
}

// 回角点
void Machine::gotoGorner(int nNum)
{
    mcWorkCmd(WORK_GOTO_GORNER,nNum);
}

// 手动加油
void Machine::manualOil(int nNum)
{
    mcWorkCmd(WORK_ACT_OIL,nNum);
}
 //梭盘计数复位
void Machine::shuttleCounter()
{
    manualAction(RESET_SHUT_COUNTER);
}
//自动换一个梭
void Machine::changeOneShuttle()
{
   manualAction(AUTO_CHANGE_ONE_SHUT);
}
//安装第一个梭壳
void Machine::installShuttle()
{
   manualAction(INSTALL_FIRST_BOBBIN);
}
//缝纫状态
void Machine::sewBuff()
{
   manualAction(SHUT_INTO_INDX_STA);
}
//换梭盘状态
void Machine::shuttleDiskBuff()
{
   manualAction(SHUT_INTO_TAKE_PLATE);
}
//将旋梭从梭盘到机头
void Machine::shuttleToHead()
{
   manualAction(SHUT_FROM_PLATE_TO_HEAD);
}
// 将旋梭从机头拿到梭盘
void Machine::headToShuttle()
{
   manualAction(SHUT_FROM_HEAD_TO_PLATE);
}

// 所有主轴研车
void Machine::allMsRun()
{
    manualAction(ALL_MS_RUN);
}

// 机头升降
void Machine::headLift()
{
    manualAction(SEW_HEAD_LIFT);
}

// 针梭复位
void Machine::msReset()
{
    manualAction(SEW_MS_RESET);
}

// 针梭去穿线位
void Machine::msToFix()
{
    manualAction(SEW_MS_TO_FIX);
}

// 手动移框
void Machine::moveFrameByHand(char xy, char dir, int spd)
{
    int para1, para2;

    if (xy == 'x' || xy == 'X')
    {
        if (dir == 'l' || dir == 'L')
        {
            para1 = XY_MOVE_LEFT;
        }
        else if (dir == 'r' || dir == 'R')
        {
            para1 = XY_MOVE_RIGHT;
        }
        else
        {
            para1 = XY_MOVE_STOP;
        }
    }
    else if (xy == 'y' || xy == 'Y')
    {
        if (dir == 'f' || dir == 'F')
        {
            para1 = XY_MOVE_FRONT;
        }
        else if (dir == 'b' || dir == 'B')
        {
            para1 = XY_MOVE_BACK;
        }
        else
        {
            para1 = XY_MOVE_STOP;
        }
    }
    else
    {
        para1 = XY_MOVE_STOP;
    }

    para2 = spd;
    manualAction(para1, para2);
}

// 缝纫剪线
void Machine::sewCutThread(int nNum)
{
    manualAction(CUT_THREAD,0,nNum);        // 加0的原因是主控上用的是para3
}

// 缝纫主轴点动
void Machine::sewJog()
{
    manualAction(SEWING_MS_JOG);
}

void Machine::mcWorkCmd(int workcode, int para1, int para2)
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.mcWork.cmdCode = UCMD_MC_WORK;
    sendPacket.mcWork.workCode = (u16)workcode;
    sendPacket.mcWork.para1 = (u32)para1;
    sendPacket.mcWork.para2 = (u16)(para2);
    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

// 启动工作
void Machine::startWork()
{
    mcWorkCmd(WORK_START);
}

// 暂停工作
void Machine::pauseWork()
{
    mcWorkCmd(WORK_PAUSE);
}

// 流程复位（结束工作）
void Machine::allToReset()
{
    mcWorkCmd(WORK_FINISH);
}

// 自动找零(全部归零)
void Machine::allToZero()
{
    mcWorkCmd(WORK_FIND_ZERO);
}

// 回起针点
void Machine::gotoStartPos()
{
    mcWorkCmd(WORK_GOTO_START);
}

// 回定位点
void Machine::gotoAnchor()
{
    mcWorkCmd(WORK_GOTO_ANCHOR);
}

// 定偏移点
void Machine::setOffsetPos()
{
    mcWorkCmd(WORK_SET_OFFSET);
}

// 回偏移点
void Machine::gotoOffsetPos()
{
    mcWorkCmd(WORK_GOTO_OFFSET);
}

// 定上料点
void Machine::setFeedPos()
{
    mcWorkCmd(WORK_SET_FEED);
}

// 回上料点
void Machine::gotoFeedPos()
{
    mcWorkCmd(WORK_GOTO_FEED);
}

// 回结束点
void Machine::gotoFinish()
{
    mcWorkCmd(WORK_GOTO_FINISH);
}

// 边框检查
void Machine::checkFrame()
{
    mcWorkCmd(WORK_CHECK_FRAME);
}

// 空走边框
void Machine::simulateFrame()
{
    mcWorkCmd(WORK_SIMULATION_FRAME);
}

/*
#define	WORK_CUT_FRAME			0x0009		// 边框切割
#define	WORK_CUT_XLINE			0x000A		// 手动断布
*/

// 快速进退
void Machine::fastJump(int idx)
{
    mcWorkCmd(WORK_FAST_JUMP, idx);
}

// 回工作点
void Machine::gotoWorkPos()
{
    mcWorkCmd(WORK_GOTO_WKPOS);
}

// 回穿线点
void Machine::gotoFixPos()
{
    mcWorkCmd(WORK_GOTO_FEEDT);
}

void Machine::gotoShuttlePos()
{
    mcWorkCmd( WORK_GOTO_CHGBO );
}

/*
#define	WORK_GOTO_CHGBO			0x000E		// 回换梭位
#define	WORK_FEED_MOVE			0x000F		// 进料退料
#define	WORK_DRAW_LATTICE		0x0010		// 画格子图
#define	WORK_GOTO_FINISH		0x0011		// 回结束点
*/

// 回零点(框架归零)
void Machine::gotoZeroPos()
{
    mcWorkCmd(WORK_GOTO_ZERO);
}

// 主轴点动
void Machine::mainShaftJog()
{
    mcWorkCmd(WORK_MS_JOG);
}

// 主轴研车
void Machine::embSpindleTest(s32 para1, s32 para2)
{
    manualAction(WIRE_MS_RUN, para1, para2);
}

// 速度改变
// chgram 主轴转速改变值。例如：参数为10表示速度加10(升速)，参数为-10表示速度减10(降速)
void Machine::msRpmChange(int chgram, int flag)
{
    mcWorkCmd(WORK_RPM_CHG, chgram, flag);
}

//----------------------------
// 移动到XY坐标命令
void Machine::moveFrameTo(int x, int y)
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.moveFrameTo.cmdCode = UCMD_MOVE_TO;
    sendPacket.moveFrameTo.posx = x;
    sendPacket.moveFrameTo.posy = y;
    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

void Machine::breakFileTrans()
{
    m_transBreak = 1;
}

#define SEND_STEP0      0
#define SEND_STEP1      1
#define SEND_STEP2      2
#define SEND_STEP3      3
#define SEND_STEP4      4
#define SEND_STEP5      5

#define SEND_STEP_MAX   10

#define SEND_ANSWER     100

void Machine::onSendTimer(void)
{
    int rslt;
    rslt = 0;

    //qDebug("file trans timer");

    if (m_transBreak != 0)      // 中断传输
    {
        qDebug("break file trans");
        m_transCtrl.transphase = SEND_STEP5;
    }

    if (m_transCtrl.transphase == SEND_STEP0)      // 文件失效
    {
        m_fileTransEn = 0;
        qDebug("SEND_STEP1 InvalidateWorkFile ");
        invalidateWorkFile(m_transCtrl.fileIdx);        // 文件失效
        m_transCtrl.transphase = SEND_STEP1;
        rslt = 1;
    }
    else if (m_transCtrl.transphase == SEND_STEP1)      // 启动文件传输
    {
        m_fileTransEn = 0;
        startFileTrans(m_transCtrl);

        qDebug("StartFileTrans ");

        qDebug("trans progress %d/%d", 0, m_transCtrl.packetNum);
        m_totalSendNum = 0;
        m_totalPacketNum = m_transCtrl.packetNum;
        emit(siTransProgress(m_transCtrl.fileType, m_totalSendNum, m_totalPacketNum));     // 发送进度信号
        m_transCtrl.transphase = SEND_STEP2;
        rslt = 1;

    }
    else if (m_transCtrl.transphase == SEND_STEP2)       // 读取传输结果
    {
        qDebug("SEND_STEP2 send GetTransResult cmd ");

        m_fileTransEn = 0;
        getTransResultFromMachine(m_transCtrl.fileId);
        m_transCtrl.transphase = SEND_STEP3;
        rslt = 1;
    }
    else if (m_transCtrl.transphase == SEND_STEP3)       // 根据传输结果传输文件数据
    {
        if (m_fileTransEn == 1)
        {
            qDebug("GetTransResult from machine");

            if (m_transCtrl.transActive == TRANS_ACTIVE)
            {
                if (    m_transCtrl.transflag == TRANS_READY ||  // 准备好接收
                        m_transCtrl.transflag == TRANS_DOING ||  // 正在接收
                        0   )
                {
                    qDebug("trans sta = TRANS_READY or TRANS_DOING flag=%d", m_transCtrl.transflag);

#if (1)
                    int i, j;
                    int thissendnum = 0;
                    int totalsendnum = 0;
                    int send_count = 1000;

#if(1)//发一个包查询一次结果
                    if ( m_transCtrl.fileType == FILE_TYPE_DAT )//花样文件（大文件）
                    {
                        if(m_connectMode == USE_TCP_COMM)//网口
                        {
                            send_count = 400;
                        }
                        else if(m_connectMode == USE_SERIAL_COMM)//串口
                        {
                            send_count = 10;
                        }
                    }
                    else if ( m_transCtrl.fileType == FILE_TYPE_PGM ) //升级等文件（小文件）
                    {
                        send_count = 25;
                    }
#endif

                    u8 mod, temp;
                    for (i = 0; i < m_transCtrl.lenBmp; i++)
                    {
                        temp = m_transCtrl.rsvBitmap[i];
                        mod = 0x01;
                        for (j = 0; j < 8; j++)
                        {
                            if ((temp & mod) == 0)
                            {
                                if (thissendnum < send_count )       // 每发送send_count个包，查询一次结果
                                {
                                    thissendnum++;

                                    transFileData(m_transCtrl, i*8+j);

                                }
                            }
                            else
                            {
                                totalsendnum++;
                            }
                            mod <<= 1;
                        }
                    }
                    m_totalSendNum = totalsendnum;
                    m_totalPacketNum = m_transCtrl.packetNum;
                    emit(siTransProgress(m_transCtrl.fileType, m_totalSendNum, m_totalPacketNum));             // 发送进度信号
                    m_transCtrl.transphase = SEND_STEP2;     // 重新发送查询命令
#else
                    int i, j;
                    int thissendnum = 0;
                    int totalsendnum = 0;
                    u8 mod, temp;
                    for (i = 0; i < m_transCtrl.lenBmp; i++)
                    {
                        temp = m_transCtrl.rsvBitmap[i];
                        mod = 0x01;
                        for (j = 0; j < 8; j++)
                        {
                            if ((temp & mod) == 0)
                            {
                                if (thissendnum < 200)       // 每发送200个包，查询一次结果，
                                {
                                    thissendnum++;
                                    TransFileData(m_transCtrl, i*8+j);
                                    qDebug("TransFileData idx=%d", i*8+j);
                                }
                            }
                            else
                            {
                                totalsendnum++;
                            }
                            mod <<= 1;
                        }
                    }
                    qDebug("trans progress = %d/%d", totalsendnum , m_transCtrl.packetNum);

                    emit(SiTransProgress(totalsendnum, m_transCtrl.packetNum));     // 发送进度信号
                    m_transCtrl.transphase = SEND_STEP2;     // 重新发送查询命令
#endif
                }
                else if (m_transCtrl.transflag == TRANS_DONE)    // 接收完成
                {
                    qDebug("trans sta = TRANS_DONE");

                    emit siSendDataDone();

                    m_totalSendNum = m_transCtrl.packetNum;
                    m_totalPacketNum = m_transCtrl.packetNum;
                    emit(siTransProgress(m_transCtrl.fileType, m_totalSendNum, m_totalPacketNum));     // 发送进度信号
                    m_transCtrl.transphase = SEND_STEP4;

                    //qDebug()<<"m_transCtrl.fileType"<<m_transCtrl.fileType;
                    if( m_transCtrl.fileType == FILE_TYPE_DAT)
                    {

                    }
                    else if( m_transCtrl.fileType == FILE_TYPE_PGM )
                    {
                        qDebug() << "UpdateFirmware";
                        updateFirmware();
                    }
                }
                else if (m_transCtrl.transflag == TRANS_REQUEST)    // 请求传输数据模式
                {
                    qDebug("trans sta = TRANS_REQUEST, sta=%d", m_transCtrl.transflag);
                    m_transCtrl.transphase = SEND_ANSWER;
                }
                else // if (m_transCtrl.transflag == TRANS_NOT_BEG) // 没有收到启动命令
                {
                    qDebug("trans sta = TRANS_NOT_BEG, sta=%d, back to SEND_STEP1", m_transCtrl.transflag);
                    m_transCtrl.transphase = SEND_STEP1;    // 重新发送启动文件传输
                }
            }
            else
            {
                qDebug("transActive != TRANS_ACTIVE, back to SEND_STEP1 ");
                m_transCtrl.transphase = SEND_STEP1;    // 重新发送启动文件传输
            }
            rslt = 1;
        }
        else
        {
            if (m_transCtrl.waitcount > SEND_STEP_MAX)      // 1秒没有回复
            {
                qDebug("waitcount > SEND_STEP_MAX, back to SEND_STEP2 ");
                m_transCtrl.transphase = SEND_STEP2;     // 重新发送查询命令
                rslt = 1;
            }
        }
    }

    if (rslt == 0)
    {
        m_transCtrl.waitcount++;
    }
    else
    {
        m_transCtrl.waitcount = 0;
    }

    if (    m_transCtrl.transphase != SEND_STEP1 &&
            m_transCtrl.transphase != SEND_STEP2 &&
            m_transCtrl.transphase != SEND_STEP3    )       // 结束
    {
        qDebug("trans file over, step=%d", m_transCtrl.transphase);
        if (m_transCtrl.transphase == SEND_STEP4)
        {
            m_totalSendNum = 0;
            m_totalPacketNum = 0;
            emit(siTransProgress(m_transCtrl.fileType, m_totalSendNum, m_totalPacketNum));        // 发送结束信号（成功）
        }
        else
        {
            m_totalSendNum = -1;
            m_totalPacketNum = -1;
            emit(siTransProgress(m_transCtrl.fileType, m_totalSendNum, m_totalPacketNum));      // 发送结束信号（失败）
        }
        m_pSendTimer->stop();               // 停止定时器
        m_transCtrl.filetransing = 0;
    }
}

//串口是否打开
void Machine::slIfOpenSerialPort(int val)
{
    if(val != 0)
    {
        if(m_connectMode == USE_SERIAL_COMM)
        {
            m_connected = 3;//串口已打开
        }
    }
}

// 发送文件过程
int Machine::sendFileProc(int type, int idx, int id, DataDs16FileHead & fileHead, u8 * pDatBuff)
{
    return sendFileProc(type, idx, id, &fileHead, pDatBuff);
}
int Machine::sendFileProc(int type, int idx, int id, DataDs16FileHead * pfileHead, u8 * pDatBuff)
{
    if (pDatBuff == NULL || pfileHead == NULL)
    {
        return -1;
    }

    if ( pfileHead->dataSize <= 0 || pfileHead->dataSize > MAX_FILE_SIZE)
    {
        qDebug("pfileHead->dataSize <= 0 || pfileHead->dataSize > MAX_FILE_SIZE, not support");
        return -2;
    }

    QTime delayTime;
    int counter = 0;
    delayTime.start();

    if (m_transCtrl.filetransing != 0)      // 已经有文件在传输
    {
        return -3;
    }

    while (m_transCtrl.filetransing != 0)   // 已经有文件在传输
    {
        if (delayTime.elapsed() > 1000)
        {
            counter++;
            qDebug("%d. wait old file trans over", counter);
            delayTime.restart();
        }

        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    }

    m_transBreak = 0;

    m_transCtrl.fileType = (u8)type;
    m_transCtrl.fileIdx = (u8)idx;
    m_transCtrl.fileId = (u16)id;
    memcpy(m_transCtrl.pFileHead, pfileHead, sizeof(DataDs16FileHead));
    memcpy(m_transCtrl.pDatBuff, pDatBuff, pfileHead->dataSize);
    m_transCtrl.packetSize = MAX_EXDP_LEN;
    m_transCtrl.packetNum = (pfileHead->dataSize + MAX_EXDP_LEN - 1) / MAX_EXDP_LEN;

    qDebug("StartFileTrans, fileType=%d, fileIdx=%d, fileId=%d, packetNum=%d, ",
           m_transCtrl.fileType, m_transCtrl.fileIdx, m_transCtrl.fileId, m_transCtrl.packetNum);

    m_transCtrl.transphase = SEND_STEP1;
    m_transCtrl.filetransing = 1;

    m_pSendTimer->start();
    return 0;
}

//  发送文件过程
int Machine::sendAPPFileProc(int type, int idx, int id, AppFileHead & fileHead, u8 * pDatBuff)
{
    if (pDatBuff == NULL || fileHead.dataSize <= 0)
    {
        return -1;
    }

    if (fileHead.dataSize > MAX_FILE_SIZE)
    {
        qDebug("fileHead.dataSize > MAX_FILE_SIZE, not support");
        return -2;
    }

    QTime delayTime;
    int counter = 0;
    delayTime.start();

    while (m_transCtrl.filetransing != 0)   // 已经有文件在传输
    {
        if (delayTime.elapsed() > 1000)
        {
            counter++;
            qDebug("%d. wait old file trans over", counter);
            delayTime.restart();
        }

        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    }

    m_transBreak = 0;

    // 拷贝数据到传输控制结构
    m_transCtrl.fileType = (u8)type;
    m_transCtrl.fileIdx = (u8)idx;
    m_transCtrl.fileId = (u16)id;
    memcpy(m_transCtrl.pAppHead, &fileHead, sizeof(AppFileHead));
    memcpy(m_transCtrl.pDatBuff, pDatBuff, fileHead.dataSize);
    m_transCtrl.packetSize = MAX_EXDP_LEN;
    m_transCtrl.packetNum = (fileHead.dataSize + MAX_EXDP_LEN - 1 ) / MAX_EXDP_LEN;

    qDebug("StartFileTrans, fileType=%d, fileIdx=%d, fileId=%d, packetNum=%d, ",
           m_transCtrl.fileType, m_transCtrl.fileIdx, m_transCtrl.fileId, m_transCtrl.packetNum);

    m_transCtrl.transphase = SEND_STEP1;
    m_transCtrl.filetransing = 1;

    // 启动定时器
    m_pSendTimer->start();
    return 0;
}

// 启动文件传输
void Machine::startFileTrans(FileTransCtrl & transCtrl)
{
    int rslt;
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.startTrans.cmdCode = UCMD_START_TRANS;
    sendPacket.startTrans.fileType = transCtrl.fileType;
    sendPacket.startTrans.fileIdx = transCtrl.fileIdx;
    sendPacket.startTrans.fileId = transCtrl.fileId;

    if( transCtrl.fileType == FILE_TYPE_DAT)
    {
        rslt = packetAVLDP(&sendPacket.packet, (u8*)transCtrl.pFileHead, sizeof(DataDs16FileHead));
    }
    else if( transCtrl.fileType == FILE_TYPE_PGM )
    {
        rslt = packetAVLDP(&sendPacket.packet, (u8*)transCtrl.pAppHead, sizeof(AppFileHead));
    }
    else
    {
        return ;
    }

    if (rslt == 0)
    {
        if( transCtrl.fileType == FILE_TYPE_DAT)
        {
            QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET+sizeof(DataDs16FileHead));
            emit(siSendData(dat));
        }
        else if( transCtrl.fileType == FILE_TYPE_PGM )
        {
            QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET+sizeof(AppFileHead));
            emit(siSendData(dat));
        }
    }
}

// 文件数据传输
void Machine::transFileData(FileTransCtrl & transCtrl, int pktidx)
{
    int rslt;
    int actsize;
    u8 buff[MAX_EXDP_LEN];

    if (pktidx < 0 || transCtrl.pDatBuff == NULL)
    {
        return;
    }

    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.transFileData.cmdCode = UCMD_TRANS_FILE_DATA;
    sendPacket.transFileData.fileId = transCtrl.fileId;
    sendPacket.transFileData.pktIdx = pktidx;

    if (pktidx < (int)transCtrl.packetNum)
    {
        if( transCtrl.fileType == FILE_TYPE_DAT)
        {
            actsize = transCtrl.pFileHead->dataSize - pktidx*transCtrl.packetSize;

            if (actsize >= transCtrl.packetSize)
            {
                actsize = transCtrl.packetSize;
            }
            else
            {
                memset(buff, 0, MAX_EXDP_LEN);
            }
        }
        else if( transCtrl.fileType == FILE_TYPE_PGM )
        {
            actsize = transCtrl.pAppHead->dataSize - pktidx*transCtrl.packetSize;

            if (actsize >= transCtrl.packetSize)
            {
                actsize = transCtrl.packetSize;
            }
            else
            {
                memset(buff, 0XFF, MAX_EXDP_LEN);
            }
        }
        else
        {
            actsize = 0;
        }

        memcpy(buff, &(transCtrl.pDatBuff[pktidx*transCtrl.packetSize]), actsize);
        //qDebug("TransFileData pktidx=%d", pktidx);
#if (0)
        int i;
        for (i = 0; i < MAX_EXDP_LEN/16; i++)
        {
            qDebug("0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x",
                   buff[i*16+0], buff[i*16+1],buff[i*16+2],buff[i*16+3],buff[i*16+4],buff[i*16+5],buff[i*16+6],buff[i*16+7],
                    buff[i*16+8],buff[i*16+9],buff[i*16+10],buff[i*16+11],buff[i*16+12],buff[i*16+13],buff[i*16+14],buff[i*16+15]);
        }

#endif
        rslt = packetAVLDP(&sendPacket.packet, buff, MAX_EXDP_LEN);
        if (rslt == 0)
        {
            QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET+MAX_EXDP_LEN);
            emit(siSendData(dat));
        }
    }
}
// 下位机升级
void Machine::updateFirmware()
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.mcUpdate.cmdCode  = UCMD_MC_UPDATE;
    sendPacket.mcUpdate.upObj     = 0;
    sendPacket.mcUpdate.upFileID  = 0;
    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

// 恢复出厂设置
void Machine::restoreFactorySetting(int type)
{
    int mctype = -1;
    int wktype = -1;
//    int gainType = -1;
    if (type == -1)
    {
        mctype = SEW_MCPARA_DEF_MC;
        wktype = SEW_MCPARA_DEF_WK;
//        gainType = DCMD_SEND_MOTO_GAINPARA;
        m_mcParaEn = 0;
        m_wkParaEn = 0;
        m_gainParaEn = 0;
    }
    else
    {
        if(type == SEW_MCPARA_DEF_MC )
        {
            mctype = SEW_MCPARA_DEF_MC;
            m_mcParaEn = 0;
        }
        if(type == SEW_MCPARA_DEF_WK )
        {
            wktype = SEW_MCPARA_DEF_WK;
            m_wkParaEn = 0;
        }
        if(type == DCMD_SEND_MOTO_GAINPARA )
        {
//            gainType = DCMD_SEND_MOTO_GAINPARA;
            m_gainParaEn = 0;
        }
    }

    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.getMcParas.cmdCode = UCMD_GET_MC_PARAS;

    if (mctype == SEW_MCPARA_DEF_MC)
    {
        sendPacket.getMcParas.paraType = (u16)mctype;
        packetAFLDP(&sendPacket.packet);

        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
        emit(siSendData(dat));
    }

    if (wktype == SEW_MCPARA_DEF_WK)
    {
        sendPacket.getMcParas.paraType = (u16)wktype;
        packetAFLDP(&sendPacket.packet);

        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
        emit(siSendData(dat));
    }

    sleep(3);
    setMcPara(&m_mcPara);
    setWkPara(&m_wkPara);
    setMcPara(&m_mcPrePara);
    setWkPara(&m_wkPrePara);
}

void Machine::sleep(int sec)
{
    QTime dieTime = QTime::currentTime().addSecs(sec);//延时sec秒
    //QTime dieTime = QTime::currentTime().addMSecs(msec);//延时msec毫秒
    while( QTime::currentTime() < dieTime )
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}

void Machine::setTcpConnectState(int state)
{
    if(state == 0){}//为了去掉串口下的构建警告
    if(m_connectMode == USE_TCP_COMM)
    {
        if(m_pTcpClient != NULL)
        {
            m_pTcpClient->m_connected = state;
        }
    }
    else if(m_connectMode == USE_SERIAL_COMM)//串口
    {
        //注释掉此行代码，因为串口发送文件较慢，若是超过5秒不给上位机返状态就会检测断开，其实并未断开
        //m_connected = state;//改变连接状态
    }
}

// 设置经过的时间
void Machine::setElapsed(unsigned char i_type ,  unsigned char  i_time)
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.setElapsedTime.cmdCode = UCMD_SET_ELAPSED_TIME;

    sendPacket.setElapsedTime.type = i_type  ;
    sendPacket.setElapsedTime.time = i_time  ;

    packetAFLDP(&sendPacket.packet);
    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

// 测试断线检测,1是面线，2是底线
void Machine::testThreadBK(int type,int needle)
{
    actionByhand(TEST_THREADBK, type, needle);
}

// 设置机器的密钥
void Machine::setMacKey(unsigned char * p_dat ,  int i_size)
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.setMacKey.cmdCode = UCMD_SET_INSTALLMENT;

    memcpy( sendPacket.setMacKey.exData ,  p_dat , i_size);

    packetAVLDP(&sendPacket.packet, (u8*)p_dat, i_size);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET + i_size );

    emit(siSendData(dat));
}
